from typing import Optional
from pydantic import BaseModel
from config import bn, db
import time
import hmac
import hashlib
import requests
import h5py
import json
from urllib.parse import urlencode

def get_user_data(username: str):
    try:
        # 读取数据文件（'r' 表示只读）
        with h5py.File(db.user_data, 'r') as f:
            # 读取嵌套组中的数据集
            data_list = f[username][()]
            # 把JSON字符串反序列化回对象
            data = json.loads(data_list.decode('utf-8')) 
        return data
    except Exception as e:
        return None

class BinanceKey(BaseModel):
    binance_key: Optional[str] = ''
    binance_secret: Optional[str] = ''

class Binance:
    def __init__(self, username, params: BinanceKey = None):
        user = get_user_data(username)
        self.time_offset = 0
        self.secret = (params and params.binance_secret) or user['binance_secret']
        self.headers = {
            'X-MBX-APIKEY': (params and params.binance_key) or user['binance_key']
        }

    def get_signed_query(self, params):
        query_string = urlencode(params)
        signature = hmac.new(self.secret.encode('utf-8'), query_string.encode('utf-8'), hashlib.sha256).hexdigest()
        return f"{query_string}&signature={signature}"

    def _get_time_offset(self):
        response = requests.get(bn.time)
        res = response.json()
        if res['serverTime']:
            return res['serverTime']
        else:
            return int(time.time() * 1000)

    def synced(self, link: str, params = {}, method: str = 'get'):
        timestamp = self._get_time_offset()
        params['timestamp'] = timestamp
        signed_query = self.get_signed_query(params)

        url = f"{link}?{signed_query}"
        if method == 'post':
            response = requests.post(url, headers=self.headers)
        elif method == 'put':
            response = requests.put(url, headers=self.headers)
        elif method == 'delete':
            response = requests.delete(url, headers=self.headers)
        else:
            response = requests.get(url, headers=self.headers)
        return response.json()

